package br.com.minilocadora.dao.implementacao;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Repository;

import br.com.minilocadora.dao.FuncionarioDao;
import br.com.minilocadora.modelo.Funcionario;

@Repository
public class FuncionarioDaoImpl implements FuncionarioDao {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1844009315216978709L;

	private EntityManager em;

	private Integer rowCount;
	
	@Override
	public Integer incluir(Funcionario funcionario) throws Exception {
	
		funcionario.setCodigo(null);
		
		em.persist(funcionario);
		
		return funcionario.getCodigo();
	}

	@Override
	public void excluir(Funcionario funcionario) throws Exception {
		
		funcionario = em.merge(funcionario);
		
		em.remove(funcionario);
		
		
	}

	@Override
	public void alterar(Funcionario funcionario) throws Exception {
		
		em.merge(funcionario);
		
	}

	@Override
	public List<Funcionario> listar(Integer first, Integer pageSize, String sortField,
			String ordenacao, Map<String, String> filters) throws Exception {
		
		CriteriaBuilder builder = em.getCriteriaBuilder();
		CriteriaQuery<Funcionario> cQuery = builder.createQuery(Funcionario.class);
		Root<Funcionario> from = cQuery.from(Funcionario.class);
		CriteriaQuery<Funcionario> select = cQuery.select(from);
		
		List<Predicate> predicates = new ArrayList<Predicate>();
		for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();)
		{
			String filterProperty = it.next();
            String filterValue = filters.get(filterProperty);
            
            Expression<String> expression = from.get(filterProperty);
            
            switch(filterProperty)
            {
            	case "dataNascimento":
            		predicates.add(builder.equal(expression, new SimpleDateFormat("dd/MM/yyyy").parse(filterValue)));
            		break;
            		
            	case "codigo":
            		predicates.add(builder.equal(expression, filterValue));
            		break;
            		
            	default:
            	{
            		predicates.add(builder.like(expression, "%" + filterValue + "%"));
            	}
            }
            
            
            
		}
		select.where(predicates.toArray(new Predicate[] {}));
		
		// total de registros feito pelo select
		CriteriaQuery<Long> countQuery = builder.createQuery(Long.class);
		countQuery.select(builder.count(countQuery.from(Funcionario.class)));
		em.createQuery(countQuery);
		rowCount = (int) (em.createQuery(countQuery).getSingleResult() + 0);
		
		
		// realiza a consulta paginada
		TypedQuery<Funcionario> listQuery = em.createQuery(select);
		listQuery.setFirstResult(first);
		listQuery.setMaxResults(pageSize);
		
		return listQuery.getResultList();
		
	}

	public EntityManager getEm() {
		return em;
	}

	@PersistenceContext
	public void setEm(EntityManager em) {
		this.em = em;
	}

	@Override
	public Integer totalDeRegistro() throws Exception {
		 
		// total de registros feito pelo select
		return this.rowCount;
	}

}
